#include "p12_loader.h"
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//从pkcs12加在私钥
EVP_PKEY* load_private_key_from_pkcs12(const char *p12_path, const char *passwd) {
    FILE *f = fopen(p12_path, "rb");
    if (!f) { perror("fopen"); return NULL; }
    PKCS12 *p12 = d2i_PKCS12_fp(f, NULL);
    fclose(f);
    if (!p12) { fprintf(stderr, "d2i_PKCS12_fp failed\n"); return NULL; }
    EVP_PKEY *pkey = NULL;
    X509 *cert = NULL;
    if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) {
        fprintf(stderr, "PKCS12_parse failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
        PKCS12_free(p12);
        return NULL;
    }
    if (cert) X509_free(cert);
    PKCS12_free(p12);
    return pkey; /* 调用者负责 EVP_PKEY_free */
}

/* 获取 p12 中证书的公钥指纹（SM3 或 SHA256），以 hex 输出 */
int get_cert_pubkey_fingerprint(const char *p12_path, const char *passwd, char *out_hex, size_t out_hex_len) {
    FILE *f = fopen(p12_path, "rb");
    if (!f) return -1;
    PKCS12 *p12 = d2i_PKCS12_fp(f, NULL);
    fclose(f);
    if (!p12) return -1;
    EVP_PKEY *pkey = NULL;
    X509 *cert = NULL;
    if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) { PKCS12_free(p12); return -1; }
    PKCS12_free(p12);
    if (!cert) { if (pkey) EVP_PKEY_free(pkey); return -1; }

    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned int mdlen = 0;
    const EVP_MD *mdalg = EVP_get_digestbyname("sm3");  
    // const EVP_MD *mdalg = EVP_sm3();  ----------------------------------
    if (!mdalg) mdalg = EVP_sha256(); /* fallback */

    unsigned char *der = NULL;
    int derlen = i2d_X509(cert, &der);
    if (derlen <= 0) { X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }

    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    if (!ctx) { OPENSSL_free(der); X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }
    if (EVP_DigestInit_ex(ctx, mdalg, NULL) != 1) { EVP_MD_CTX_free(ctx); OPENSSL_free(der); X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }
    if (EVP_DigestUpdate(ctx, der, derlen) != 1) { EVP_MD_CTX_free(ctx); OPENSSL_free(der); X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }
    if (EVP_DigestFinal_ex(ctx, md, &mdlen) != 1) { EVP_MD_CTX_free(ctx); OPENSSL_free(der); X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }
    EVP_MD_CTX_free(ctx);
    OPENSSL_free(der);

    /* hex 输出 */
    static const char hex[] = "0123456789abcdef";
    if (out_hex_len < mdlen*2 + 1) { X509_free(cert); if (pkey) EVP_PKEY_free(pkey); return -1; }
    for (unsigned int i = 0; i < mdlen; ++i) {
        out_hex[i*2] = hex[(md[i] >> 4) & 0xF];
        out_hex[i*2+1] = hex[md[i] & 0xF];
    }
    out_hex[mdlen*2] = '\0';

    X509_free(cert);
    if (pkey) EVP_PKEY_free(pkey);
    return 0;
}
